package main

import (
	"fmt"
)

const (
	WIDTH  = 1920
	HEIGHT = 1080
)

type pixel int

var screen [WIDTH][HEIGHT]pixel

func main() {
	var arr1 [5]int
	for i := 0; i < len(arr1); i++ {
		arr1[i] = i * 2
	}
	for i := 0; i < len(arr1); i++ {
		fmt.Printf("Array at index %d is %d\n", i, arr1[i])
	}

	f(arr1)
	fp(&arr1)

	for y := 0; y < HEIGHT; y++ {
		for x := 0; x < WIDTH; x++ {
			screen[x][y] = 0
		}
	}

	array := [3]float64{7.0, 8.5, 9.1}
	x := sum(&array)
	fmt.Printf("The sum of the array is: %f\n", x)

	array_slices()

	make_slice()

	exec73()

	exec74()

	forRangeSlice()
	forRangeSlice2()
	exec77()

	copyAppendSlice()
	s:=[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
	fmt.Println(s)
	fn := func(value int) bool{
		return value % 2 == 0
	}

	s = filterSlice(s, fn)
	fmt.Println("-----------------------------")
	fmt.Println(s)
	fmt.Printf("S's length is:%d\n", len(s))

	ss := "\u00ff\u754c"
	for i, c:=range ss{
		fmt.Printf("%d:%c ", i, c)
	}

	str := "hello world"
	s1, s2:=exec712(str, 5)
	fmt.Printf("s1: %s, s2: %s\n", s1, s2)
	fmt.Printf("Result: %s\r\n", exec713(str))
	fmt.Printf("Result: %s\r\n", exec714(str))

	nlist := []int{1, 2, 3, 4, 5,}
	fmt.Println(nlist)
	nlist = exec717(test, nlist)
	fmt.Printf("new list: \n")
	fmt.Println(nlist)

}

/**
在函数式编程语言中，一个 map-function 是指能够接受一个函数原型和一个列表，并使用列表中的值依次执行函数原型，
公式为：map ( F(), (e1,e2, . . . ,en) ) = ( F(e1), F(e2), ... F(en) )。

编写一个函数 mapFunc 要求接受以下 2 个参数：

一个将整数乘以 10 的函数
一个整数列表
最后返回保存运行结果的整数列表。
 */
func exec717(rideTen func(a int) int, list []int) []int  {
	for i := 0; i < len(list); i++ {
		list[i] = list[i] * 10
	}
	return list
}

func test(a int)int  {
	return a * 10
}

/**
编写一个程序，要求能够反转字符串，即将 "Google" 转换成 "elgooG"（提示：使用 []byte 类型的切片）。
 */
func exec714(str string)string  {
	c := []byte(str)
	length := len(c)
	nc := make([]byte, length)

	for i := length - 1; i >= 0 ; i-- {
		nc[length - 1 - i] = c[i]
	}

	return string(nc)
}

/**
假设有字符串 str，那么 str[len(str)/2:] + str[:len(str)/2] 的结果是什么？
 */
func exec713(str string) string  {
	return str[len(str)/2:] + str[:len(str)/2]
}

/**
编写一个函数，要求其接受两个参数，原始字符串 str 和分割索引 i，然后返回两个分割后的字符串。
 */
func exec712(s string, index int) (s1, s2 string)  {
	s1 = s[:index]
	s2 = s[index:]
	return
}

/**
用顺序函数过滤容器：s 是前 10 个整型的切片。
构造一个函数 Filter，第一个参数是 s，第二个参数是一个 fn func(int) bool，返回满足函数 fn 的元素切片。
通过 fn 测试方法测试当整型值是偶数时的情况。
 */
func filterSlice(s []int, fn func(int) bool) []int  {
	ns := make([]int, len(s))
	for _, value:=range s{
		if fn(value) {
			ns = append(ns, value)
		}
	}
	s = ns
	return s
}

/**
给定一个切片 s []int 和一个 int 类型的因子 factor，扩展 s 使其长度为 len(s) * factor。
 */
func magnifySlice(s []int, factor int) []int {
	ns:=make([]int, len(s) * factor)
	copy(ns, s)
	s = ns
	return s
}

func copyAppendSlice() {
	slFrom:=[]int{1, 2, 3}
	s1To := make([]int, 10)

	n := copy(s1To, slFrom)
	fmt.Println(s1To)
	fmt.Printf("Copied %d elements\n", n)

	sl3 := []int{1, 2, 3}
	sl3 = append(sl3, 4, 5, 6)
	fmt.Println(sl3)
}



/**
如果 a 是一个切片，那么 a[n:n] 的长度是多少？
	a[n:n] = 0
a[n:n+1] 的长度又是多少？
	a[n:n+1] = 1
 */
func exec77() {
	a:= make([]byte, 5)
	fmt.Printf("a[3:3]'s length is %d\n", len(a[3:3]))
	fmt.Printf("a[3:4]'s length is %d\n", len(a[3:4]))
}

func forRangeSlice2() {
	seasons := []string{"spring", "summer", "autumn", "winter"}
	for ix, season:=range seasons{
		fmt.Printf("Season %d is:%s\n", ix, season)
	}

	var season string
	for _, season = range seasons{
		fmt.Printf("%s\n", season)
	}
}

func forRangeSlice()  {
	var slice1 []int = make([]int, 4)
	slice1[0] = 1
	slice1[1] = 2
	slice1[2] = 3
	slice1[3] = 4

	for ix, value:=range slice1{
		fmt.Printf("Slice at %d is: %d\n ", ix, value)
	}

}

/**
假设 s1 := []byte{'p', 'o', 'e', 'm'} 且 s2 := s1[2:]，s2 的值是多少？
	s2 = {'e', 'm'}
如果我们执行 s2[1] = 't'，s1 和 s2 现在的值又分别是多少？
	s1 = {'p', 'o', 'e', 't'}
	s2 = {'e', 't'}
 */
func exec74() {
	s1 := []byte{'p', 'o', 'e', 'm'}
	s2 := s1[2:]
	fmt.Printf("s1 = %+v\r\n", s1)
	fmt.Printf("s2 = %+v\r\n", s2)
	s2[1] = 't'
	fmt.Printf("s1 = %+v\r\n", s1)
	fmt.Printf("s2 = %+v\r\n", s2)
}
/**
	给定 s := make([]byte, 5)，len(s) 和 cap(s) 分别是多少？
		len(s) = 5
		cap(s) = 5
	s = s[2:4]，len(s) 和 cap(s) 又分别是多少？
		len(s) = 2
		cap(s) = 3
 */
func exec73() {
	s := make([]byte, 5)
	fmt.Printf("\n length of s is: %d\n", len(s))
	fmt.Printf("capacity of s is: %d\n", cap(s))
	s = s[2:4]
	fmt.Printf("\nlength of slice s is: %d\n", len(s))
	fmt.Printf("capacity of slice s is: %d\n", cap(s))
}

func make_slice() {
	var slice1 []int =make([]int, 10, 20)
	for i:=0; i <len(slice1); i++ {
		slice1[i] = 5 * i
	}

	for i:= 0; i < len(slice1); i++ {
		fmt.Printf("Slice at %d is %d\n", i, slice1[i])
	}

	fmt.Printf("\nThe length of the slice1 is %d\n", len(slice1))
	fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
}

func array_slices() {
	var arr1 [6]int
	var slice1 []int = arr1[2:5]

	for i := 0; i < len(arr1); i++ {
		arr1[i] = i
	}

	for i := 0; i < len(slice1); i++ {
		fmt.Printf("Slice at %d is %d\n", i, slice1[i])
	}

	fmt.Printf("The length of arr1 is %d\n", len(arr1))
	fmt.Printf("The length of slice1 is %d\n", len(slice1))
	fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))

	slice1 = slice1[0:4]
	for i := 0; i < len(slice1); i++ {
		fmt.Printf("Slice at %d is %d\n", i, slice1[i])
	}
	fmt.Printf("The length of slice1 is %d\n", len(slice1))
	fmt.Printf("The capcacity of slice1 is %d\n", cap(slice1))
}

func sum(a *[3]float64) (sum float64) {
	for _, v := range a {
		sum += v
	}
	return
}

func f(a [5]int) {
	fmt.Println(a)
}

func fp(a *[5]int) {
	fmt.Println(a)
}
